﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x0200001F RID: 31
	[Serializable]
	public class Grounding
	{
		// Token: 0x17000010 RID: 16
		// (get) Token: 0x060001AD RID: 429 RVA: 0x000032A3 File Offset: 0x000014A3
		// (set) Token: 0x060001AE RID: 430 RVA: 0x000032AB File Offset: 0x000014AB
		public Grounding.Leg[] legs { get; set; }

		// Token: 0x17000011 RID: 17
		// (get) Token: 0x060001AF RID: 431 RVA: 0x000032B4 File Offset: 0x000014B4
		// (set) Token: 0x060001B0 RID: 432 RVA: 0x000032BC File Offset: 0x000014BC
		public Grounding.Pelvis pelvis { get; set; }

		// Token: 0x17000012 RID: 18
		// (get) Token: 0x060001B1 RID: 433 RVA: 0x000032C5 File Offset: 0x000014C5
		// (set) Token: 0x060001B2 RID: 434 RVA: 0x000032CD File Offset: 0x000014CD
		public bool isGrounded { get; set; }

		// Token: 0x17000013 RID: 19
		// (get) Token: 0x060001B3 RID: 435 RVA: 0x000032D6 File Offset: 0x000014D6
		// (set) Token: 0x060001B4 RID: 436 RVA: 0x000032DE File Offset: 0x000014DE
		public Transform root { get; set; }

		// Token: 0x17000014 RID: 20
		// (get) Token: 0x060001B5 RID: 437 RVA: 0x000032E7 File Offset: 0x000014E7
		// (set) Token: 0x060001B6 RID: 438 RVA: 0x000032EF File Offset: 0x000014EF
		public RaycastHit rootHit { get; set; }

		// Token: 0x17000015 RID: 21
		// (get) Token: 0x060001B7 RID: 439 RVA: 0x0002124C File Offset: 0x0001F44C
		public bool rootGrounded
		{
			get
			{
				return this.rootHit.distance < this.maxStep * 2f;
			}
		}

		// Token: 0x060001B8 RID: 440 RVA: 0x00021278 File Offset: 0x0001F478
		public RaycastHit GetRootHit(float maxDistanceMlp = 10f)
		{
			RaycastHit result = default(RaycastHit);
			Vector3 up = this.up;
			result.point = this.root.position - up * this.maxStep * 10f;
			float num = maxDistanceMlp + 1f;
			result.distance = this.maxStep * num;
			if (this.maxStep <= 0f)
			{
				return result;
			}
			if (this.quality != Grounding.Quality.Best)
			{
				Physics.Raycast(this.root.position + up * this.maxStep, -up, out result, this.maxStep * num, this.layers);
			}
			else
			{
				Physics.SphereCast(this.root.position + up * this.maxStep, this.rootSphereCastRadius, -this.up, out result, this.maxStep * num, this.layers);
			}
			return result;
		}

		// Token: 0x060001B9 RID: 441 RVA: 0x00021384 File Offset: 0x0001F584
		public bool IsValid(ref string errorMessage)
		{
			if (this.root == null)
			{
				errorMessage = "Root transform is null. Can't initiate Grounding.";
				return false;
			}
			if (this.legs == null)
			{
				errorMessage = "Grounding legs is null. Can't initiate Grounding.";
				return false;
			}
			if (this.pelvis == null)
			{
				errorMessage = "Grounding pelvis is null. Can't initiate Grounding.";
				return false;
			}
			if (this.legs.Length == 0)
			{
				errorMessage = "Grounding has 0 legs. Can't initiate Grounding.";
				return false;
			}
			return true;
		}

		// Token: 0x060001BA RID: 442 RVA: 0x000213EC File Offset: 0x0001F5EC
		public void Initiate(Transform root, Transform[] feet)
		{
			this.root = root;
			this.initiated = false;
			this.rootHit = default(RaycastHit);
			if (this.legs == null)
			{
				this.legs = new Grounding.Leg[feet.Length];
			}
			if (this.legs.Length != feet.Length)
			{
				this.legs = new Grounding.Leg[feet.Length];
			}
			for (int i = 0; i < feet.Length; i++)
			{
				if (this.legs[i] == null)
				{
					this.legs[i] = new Grounding.Leg();
				}
			}
			if (this.pelvis == null)
			{
				this.pelvis = new Grounding.Pelvis();
			}
			string empty = string.Empty;
			if (!this.IsValid(ref empty))
			{
				Warning.Log(empty, root, false);
				return;
			}
			if (Application.isPlaying)
			{
				for (int j = 0; j < feet.Length; j++)
				{
					this.legs[j].Initiate(this, feet[j]);
				}
				this.pelvis.Initiate(this);
				this.initiated = true;
			}
		}

		// Token: 0x060001BB RID: 443 RVA: 0x000214F0 File Offset: 0x0001F6F0
		public void Update()
		{
			if (!this.initiated)
			{
				return;
			}
			if (this.layers == 0)
			{
				this.LogWarning("Grounding layers are set to nothing. Please add a ground layer.");
			}
			this.maxStep = Mathf.Clamp(this.maxStep, 0f, this.maxStep);
			this.footRadius = Mathf.Clamp(this.footRadius, 0.0001f, this.maxStep);
			this.pelvisDamper = Mathf.Clamp(this.pelvisDamper, 0f, 1f);
			this.rootSphereCastRadius = Mathf.Clamp(this.rootSphereCastRadius, 0.0001f, this.rootSphereCastRadius);
			this.maxFootRotationAngle = Mathf.Clamp(this.maxFootRotationAngle, 0f, 90f);
			this.prediction = Mathf.Clamp(this.prediction, 0f, this.prediction);
			this.footSpeed = Mathf.Clamp(this.footSpeed, 0f, this.footSpeed);
			this.rootHit = this.GetRootHit(10f);
			float num = float.NegativeInfinity;
			float num2 = float.PositiveInfinity;
			this.isGrounded = false;
			foreach (Grounding.Leg leg in this.legs)
			{
				leg.Process();
				if (leg.IKOffset > num)
				{
					num = leg.IKOffset;
				}
				if (leg.IKOffset < num2)
				{
					num2 = leg.IKOffset;
				}
				if (leg.isGrounded)
				{
					this.isGrounded = true;
				}
			}
			this.pelvis.Process(-num * this.lowerPelvisWeight, -num2 * this.liftPelvisWeight, this.isGrounded);
		}

		// Token: 0x060001BC RID: 444 RVA: 0x00021690 File Offset: 0x0001F890
		public Vector3 GetLegsPlaneNormal()
		{
			if (!this.initiated)
			{
				return Vector3.up;
			}
			Vector3 up = this.up;
			Vector3 vector = up;
			for (int i = 0; i < this.legs.Length; i++)
			{
				Vector3 vector2 = this.legs[i].IKPosition - this.root.position;
				Vector3 vector3 = up;
				Vector3 fromDirection = vector2;
				Vector3.OrthoNormalize(ref vector3, ref fromDirection);
				Quaternion rotation = Quaternion.FromToRotation(fromDirection, vector2);
				vector = rotation * vector;
			}
			return vector;
		}

		// Token: 0x060001BD RID: 445 RVA: 0x00021714 File Offset: 0x0001F914
		public void Reset()
		{
			if (!Application.isPlaying)
			{
				return;
			}
			this.pelvis.Reset();
			foreach (Grounding.Leg leg in this.legs)
			{
				leg.Reset();
			}
		}

		// Token: 0x060001BE RID: 446 RVA: 0x000032F8 File Offset: 0x000014F8
		public void LogWarning(string message)
		{
			Warning.Log(message, this.root, false);
		}

		// Token: 0x17000016 RID: 22
		// (get) Token: 0x060001BF RID: 447 RVA: 0x00003307 File Offset: 0x00001507
		public Vector3 up
		{
			get
			{
				return (!this.useRootRotation) ? Vector3.up : this.root.up;
			}
		}

		// Token: 0x060001C0 RID: 448 RVA: 0x0002175C File Offset: 0x0001F95C
		public float GetVerticalOffset(Vector3 p1, Vector3 p2)
		{
			if (this.useRootRotation)
			{
				return (Quaternion.Inverse(this.root.rotation) * (p1 - p2)).y;
			}
			return p1.y - p2.y;
		}

		// Token: 0x060001C1 RID: 449 RVA: 0x000217A8 File Offset: 0x0001F9A8
		public Vector3 Flatten(Vector3 v)
		{
			if (this.useRootRotation)
			{
				Vector3 onNormal = v;
				Vector3 up = this.root.up;
				Vector3.OrthoNormalize(ref up, ref onNormal);
				return Vector3.Project(v, onNormal);
			}
			v.y = 0f;
			return v;
		}

		// Token: 0x17000017 RID: 23
		// (get) Token: 0x060001C2 RID: 450 RVA: 0x00003329 File Offset: 0x00001529
		public bool useRootRotation
		{
			get
			{
				return this.rotateSolver && !(this.root.up == Vector3.up);
			}
		}

		// Token: 0x040000EC RID: 236
		[Tooltip("Layers to ground the character to. Make sure to exclude the layer of the character controller.")]
		public LayerMask layers;

		// Token: 0x040000ED RID: 237
		[Tooltip("Max step height. Maximum vertical distance of Grounding from the root of the character.")]
		public float maxStep = 0.5f;

		// Token: 0x040000EE RID: 238
		[Tooltip("The height offset of the root.")]
		public float heightOffset;

		// Token: 0x040000EF RID: 239
		[Tooltip("The speed of moving the feet up/down.")]
		public float footSpeed = 2.5f;

		// Token: 0x040000F0 RID: 240
		[Tooltip("CapsuleCast radius. Should match approximately with the size of the feet.")]
		public float footRadius = 0.15f;

		// Token: 0x040000F1 RID: 241
		[Tooltip("Amount of velocity based prediction of the foot positions.")]
		public float prediction = 0.05f;

		// Token: 0x040000F2 RID: 242
		[Range(0f, 1f)]
		[Tooltip("Weight of rotating the feet to the ground normal offset.")]
		public float footRotationWeight = 1f;

		// Token: 0x040000F3 RID: 243
		[Tooltip("Speed of slerping the feet to their grounded rotations.")]
		public float footRotationSpeed = 7f;

		// Token: 0x040000F4 RID: 244
		[Range(0f, 90f)]
		[Tooltip("Max Foot Rotation Angle. Max angular offset from the foot's rotation.")]
		public float maxFootRotationAngle = 45f;

		// Token: 0x040000F5 RID: 245
		[Tooltip("If true, solver will rotate with the character root so the character can be grounded for example to spherical planets. For performance reasons leave this off unless needed.")]
		public bool rotateSolver;

		// Token: 0x040000F6 RID: 246
		[Tooltip("The speed of moving the character up/down.")]
		public float pelvisSpeed = 5f;

		// Token: 0x040000F7 RID: 247
		[Range(0f, 1f)]
		[Tooltip("Used for smoothing out vertical pelvis movement (range 0 - 1).")]
		public float pelvisDamper;

		// Token: 0x040000F8 RID: 248
		[Tooltip("The weight of lowering the pelvis to the lowest foot.")]
		public float lowerPelvisWeight = 1f;

		// Token: 0x040000F9 RID: 249
		[Tooltip("The weight of lifting the pelvis to the highest foot. This is useful when you don't want the feet to go too high relative to the body when crouching.")]
		public float liftPelvisWeight;

		// Token: 0x040000FA RID: 250
		[Tooltip("The radius of the spherecast from the root that determines whether the character root is grounded.")]
		public float rootSphereCastRadius = 0.1f;

		// Token: 0x040000FB RID: 251
		[Tooltip("The raycasting quality. Fastest is a single raycast per foot, Simple is three raycasts, Best is one raycast and a capsule cast per foot.")]
		public Grounding.Quality quality = Grounding.Quality.Best;

		// Token: 0x040000FC RID: 252
		public bool initiated;

		// Token: 0x02000020 RID: 32
		[Serializable]
		public enum Quality
		{
			// Token: 0x04000103 RID: 259
			Fastest,
			// Token: 0x04000104 RID: 260
			Simple,
			// Token: 0x04000105 RID: 261
			Best
		}

		// Token: 0x02000021 RID: 33
		public class Leg
		{
			// Token: 0x17000018 RID: 24
			// (get) Token: 0x060001C4 RID: 452 RVA: 0x00003368 File Offset: 0x00001568
			// (set) Token: 0x060001C5 RID: 453 RVA: 0x00003370 File Offset: 0x00001570
			public bool isGrounded { get; set; }

			// Token: 0x17000019 RID: 25
			// (get) Token: 0x060001C6 RID: 454 RVA: 0x00003379 File Offset: 0x00001579
			// (set) Token: 0x060001C7 RID: 455 RVA: 0x00003381 File Offset: 0x00001581
			public Vector3 IKPosition { get; set; }

			// Token: 0x1700001A RID: 26
			// (get) Token: 0x060001C8 RID: 456 RVA: 0x0000338A File Offset: 0x0000158A
			// (set) Token: 0x060001C9 RID: 457 RVA: 0x00003392 File Offset: 0x00001592
			public Quaternion rotationOffset { get; set; }

			// Token: 0x1700001B RID: 27
			// (get) Token: 0x060001CA RID: 458 RVA: 0x0000339B File Offset: 0x0000159B
			// (set) Token: 0x060001CB RID: 459 RVA: 0x000033A3 File Offset: 0x000015A3
			public bool initiated { get; set; }

			// Token: 0x1700001C RID: 28
			// (get) Token: 0x060001CC RID: 460 RVA: 0x000033AC File Offset: 0x000015AC
			// (set) Token: 0x060001CD RID: 461 RVA: 0x000033B4 File Offset: 0x000015B4
			public float heightFromGround { get; set; }

			// Token: 0x1700001D RID: 29
			// (get) Token: 0x060001CE RID: 462 RVA: 0x000033BD File Offset: 0x000015BD
			// (set) Token: 0x060001CF RID: 463 RVA: 0x000033C5 File Offset: 0x000015C5
			public Vector3 velocity { get; set; }

			// Token: 0x1700001E RID: 30
			// (get) Token: 0x060001D0 RID: 464 RVA: 0x000033CE File Offset: 0x000015CE
			// (set) Token: 0x060001D1 RID: 465 RVA: 0x000033D6 File Offset: 0x000015D6
			public Transform transform { get; set; }

			// Token: 0x1700001F RID: 31
			// (get) Token: 0x060001D2 RID: 466 RVA: 0x000033DF File Offset: 0x000015DF
			// (set) Token: 0x060001D3 RID: 467 RVA: 0x000033E7 File Offset: 0x000015E7
			public float IKOffset { get; set; }

			// Token: 0x060001D4 RID: 468 RVA: 0x000033F0 File Offset: 0x000015F0
			public void Initiate(Grounding grounding, Transform transform)
			{
				this.initiated = false;
				this.grounding = grounding;
				this.transform = transform;
				this.up = Vector3.up;
				this.initiated = true;
				this.OnEnable();
			}

			// Token: 0x060001D5 RID: 469 RVA: 0x0000341F File Offset: 0x0000161F
			public void OnEnable()
			{
				if (!this.initiated)
				{
					return;
				}
				this.lastPosition = this.transform.position;
				this.lastTime = Time.deltaTime;
			}

			// Token: 0x060001D6 RID: 470 RVA: 0x000217EC File Offset: 0x0001F9EC
			public void Reset()
			{
				this.lastPosition = this.transform.position;
				this.lastTime = Time.deltaTime;
				this.IKOffset = 0f;
				this.IKPosition = this.transform.position;
				this.rotationOffset = Quaternion.identity;
			}

			// Token: 0x060001D7 RID: 471 RVA: 0x0002183C File Offset: 0x0001FA3C
			public void Process()
			{
				if (!this.initiated)
				{
					return;
				}
				if (this.grounding.maxStep <= 0f)
				{
					return;
				}
				this.deltaTime = Time.time - this.lastTime;
				this.lastTime = Time.time;
				if (this.deltaTime == 0f)
				{
					return;
				}
				this.up = this.grounding.up;
				this.heightFromGround = float.PositiveInfinity;
				this.velocity = (this.transform.position - this.lastPosition) / this.deltaTime;
				this.velocity = this.grounding.Flatten(this.velocity);
				this.lastPosition = this.transform.position;
				Vector3 vector = this.velocity * this.grounding.prediction;
				if (this.grounding.footRadius <= 0f)
				{
					this.grounding.quality = Grounding.Quality.Fastest;
				}
				switch (this.grounding.quality)
				{
				case Grounding.Quality.Fastest:
				{
					RaycastHit raycastHit = this.GetRaycastHit(vector);
					this.SetFootToPoint(raycastHit.normal, raycastHit.point);
					break;
				}
				case Grounding.Quality.Simple:
				{
					this.heelHit = this.GetRaycastHit(Vector3.zero);
					RaycastHit raycastHit2 = this.GetRaycastHit(this.grounding.root.forward * this.grounding.footRadius + vector);
					RaycastHit raycastHit3 = this.GetRaycastHit(this.grounding.root.right * this.grounding.footRadius * 0.5f);
					Vector3 vector2 = Vector3.Cross(raycastHit2.point - this.heelHit.point, raycastHit3.point - this.heelHit.point).normalized;
					if (Vector3.Dot(vector2, this.up) < 0f)
					{
						vector2 = -vector2;
					}
					this.SetFootToPlane(vector2, this.heelHit.point, this.heelHit.point);
					break;
				}
				case Grounding.Quality.Best:
				{
					this.heelHit = this.GetRaycastHit(Vector3.zero);
					RaycastHit capsuleHit = this.GetCapsuleHit(vector);
					this.SetFootToPlane(capsuleHit.normal, capsuleHit.point, this.heelHit.point);
					break;
				}
				}
				this.isGrounded = (this.heightFromGround < this.grounding.maxStep);
				float num = this.stepHeightFromGround;
				if (!this.grounding.rootGrounded)
				{
					num = 0f;
				}
				this.IKOffset = Interp.LerpValue(this.IKOffset, num, this.grounding.footSpeed, this.grounding.footSpeed);
				this.IKOffset = Mathf.Lerp(this.IKOffset, num, this.deltaTime * this.grounding.footSpeed);
				float verticalOffset = this.grounding.GetVerticalOffset(this.transform.position, this.grounding.root.position);
				float num2 = Mathf.Clamp(this.grounding.maxStep - verticalOffset, 0f, this.grounding.maxStep);
				this.IKOffset = Mathf.Clamp(this.IKOffset, -num2, this.IKOffset);
				this.RotateFoot();
				this.IKPosition = this.transform.position - this.up * this.IKOffset;
				float footRotationWeight = this.grounding.footRotationWeight;
				this.rotationOffset = ((footRotationWeight < 1f) ? Quaternion.Slerp(Quaternion.identity, this.r, footRotationWeight) : this.r);
			}

			// Token: 0x17000020 RID: 32
			// (get) Token: 0x060001D8 RID: 472 RVA: 0x00003449 File Offset: 0x00001649
			public float stepHeightFromGround
			{
				get
				{
					return Mathf.Clamp(this.heightFromGround, -this.grounding.maxStep, this.grounding.maxStep);
				}
			}

			// Token: 0x060001D9 RID: 473 RVA: 0x00021C08 File Offset: 0x0001FE08
			public RaycastHit GetCapsuleHit(Vector3 offsetFromHeel)
			{
				RaycastHit result = default(RaycastHit);
				Vector3 a = this.transform.position + this.grounding.root.forward * this.grounding.footRadius;
				result.point = a - this.up * this.grounding.maxStep * 2f;
				result.normal = this.up;
				Vector3 vector = a + this.grounding.maxStep * this.up;
				Vector3 point = vector + offsetFromHeel;
				Physics.CapsuleCast(vector, point, this.grounding.footRadius, -this.up, out result, this.grounding.maxStep * 3f, this.grounding.layers);
				return result;
			}

			// Token: 0x060001DA RID: 474 RVA: 0x00021CF0 File Offset: 0x0001FEF0
			public RaycastHit GetRaycastHit(Vector3 offsetFromHeel)
			{
				RaycastHit result = default(RaycastHit);
				Vector3 a = this.transform.position + offsetFromHeel;
				result.point = a - this.up * this.grounding.maxStep * 2f;
				result.normal = this.up;
				if (this.grounding.maxStep <= 0f)
				{
					return result;
				}
				Physics.Raycast(a + this.grounding.maxStep * this.up, -this.up, out result, this.grounding.maxStep * 3f, this.grounding.layers);
				return result;
			}

			// Token: 0x060001DB RID: 475 RVA: 0x0000346D File Offset: 0x0000166D
			public Vector3 RotateNormal(Vector3 normal)
			{
				if (this.grounding.quality == Grounding.Quality.Best)
				{
					return normal;
				}
				return Vector3.RotateTowards(this.up, normal, this.grounding.maxFootRotationAngle * 0.0174532924f, this.deltaTime);
			}

			// Token: 0x060001DC RID: 476 RVA: 0x000034A5 File Offset: 0x000016A5
			public void SetFootToPoint(Vector3 normal, Vector3 point)
			{
				this.toHitNormal = Quaternion.FromToRotation(this.up, this.RotateNormal(normal));
				this.heightFromGround = this.GetHeightFromGround(point);
			}

			// Token: 0x060001DD RID: 477 RVA: 0x00021DBC File Offset: 0x0001FFBC
			public void SetFootToPlane(Vector3 planeNormal, Vector3 planePoint, Vector3 heelHitPoint)
			{
				planeNormal = this.RotateNormal(planeNormal);
				this.toHitNormal = Quaternion.FromToRotation(this.up, planeNormal);
				Vector3 hitPoint = V3Tools.LineToPlane(this.transform.position + this.up * this.grounding.maxStep, -this.up, planeNormal, planePoint);
				this.heightFromGround = this.GetHeightFromGround(hitPoint);
				float heightFromGround = this.GetHeightFromGround(heelHitPoint);
				this.heightFromGround = Mathf.Clamp(this.heightFromGround, float.NegativeInfinity, heightFromGround);
			}

			// Token: 0x060001DE RID: 478 RVA: 0x000034CC File Offset: 0x000016CC
			public float GetHeightFromGround(Vector3 hitPoint)
			{
				return this.grounding.GetVerticalOffset(this.transform.position, hitPoint) - this.rootYOffset;
			}

			// Token: 0x060001DF RID: 479 RVA: 0x00021E4C File Offset: 0x0002004C
			public void RotateFoot()
			{
				Quaternion rotationOffsetTarget = this.GetRotationOffsetTarget();
				this.r = Quaternion.Slerp(this.r, rotationOffsetTarget, this.deltaTime * this.grounding.footRotationSpeed);
			}

			// Token: 0x060001E0 RID: 480 RVA: 0x00021E84 File Offset: 0x00020084
			public Quaternion GetRotationOffsetTarget()
			{
				if (this.grounding.maxFootRotationAngle <= 0f)
				{
					return Quaternion.identity;
				}
				if (this.grounding.maxFootRotationAngle >= 180f)
				{
					return this.toHitNormal;
				}
				return Quaternion.RotateTowards(Quaternion.identity, this.toHitNormal, this.grounding.maxFootRotationAngle);
			}

			// Token: 0x17000021 RID: 33
			// (get) Token: 0x060001E1 RID: 481 RVA: 0x00021EE4 File Offset: 0x000200E4
			public float rootYOffset
			{
				get
				{
					return this.grounding.GetVerticalOffset(this.transform.position, this.grounding.root.position - this.up * this.grounding.heightOffset);
				}
			}

			// Token: 0x04000106 RID: 262
			public Grounding grounding;

			// Token: 0x04000107 RID: 263
			public float lastTime;

			// Token: 0x04000108 RID: 264
			public float deltaTime;

			// Token: 0x04000109 RID: 265
			public Vector3 lastPosition;

			// Token: 0x0400010A RID: 266
			public Quaternion toHitNormal;

			// Token: 0x0400010B RID: 267
			public Quaternion r;

			// Token: 0x0400010C RID: 268
			public RaycastHit heelHit;

			// Token: 0x0400010D RID: 269
			public Vector3 up = Vector3.up;
		}

		// Token: 0x02000022 RID: 34
		public class Pelvis
		{
			// Token: 0x17000022 RID: 34
			// (get) Token: 0x060001E3 RID: 483 RVA: 0x000034EC File Offset: 0x000016EC
			// (set) Token: 0x060001E4 RID: 484 RVA: 0x000034F4 File Offset: 0x000016F4
			public Vector3 IKOffset { get; set; }

			// Token: 0x17000023 RID: 35
			// (get) Token: 0x060001E5 RID: 485 RVA: 0x000034FD File Offset: 0x000016FD
			// (set) Token: 0x060001E6 RID: 486 RVA: 0x00003505 File Offset: 0x00001705
			public float heightOffset { get; set; }

			// Token: 0x060001E7 RID: 487 RVA: 0x0000350E File Offset: 0x0000170E
			public void Initiate(Grounding grounding)
			{
				this.grounding = grounding;
				this.initiated = true;
				this.OnEnable();
			}

			// Token: 0x060001E8 RID: 488 RVA: 0x00003524 File Offset: 0x00001724
			public void Reset()
			{
				this.lastRootPosition = this.grounding.root.transform.position;
				this.lastTime = Time.deltaTime;
				this.IKOffset = Vector3.zero;
				this.heightOffset = 0f;
			}

			// Token: 0x060001E9 RID: 489 RVA: 0x00003562 File Offset: 0x00001762
			public void OnEnable()
			{
				if (!this.initiated)
				{
					return;
				}
				this.lastRootPosition = this.grounding.root.transform.position;
				this.lastTime = Time.time;
			}

			// Token: 0x060001EA RID: 490 RVA: 0x00021F34 File Offset: 0x00020134
			public void Process(float lowestOffset, float highestOffset, bool isGrounded)
			{
				if (!this.initiated)
				{
					return;
				}
				float num = Time.time - this.lastTime;
				this.lastTime = Time.time;
				if (num <= 0f)
				{
					return;
				}
				float b = lowestOffset + highestOffset;
				if (!this.grounding.rootGrounded)
				{
					b = 0f;
				}
				this.heightOffset = Mathf.Lerp(this.heightOffset, b, num * this.grounding.pelvisSpeed);
				Vector3 p = this.grounding.root.position - this.lastRootPosition;
				this.lastRootPosition = this.grounding.root.position;
				this.damperF = Interp.LerpValue(this.damperF, (!isGrounded) ? 0f : 1f, 1f, 10f);
				this.heightOffset -= this.grounding.GetVerticalOffset(p, Vector3.zero) * this.grounding.pelvisDamper * this.damperF;
				this.IKOffset = this.grounding.up * this.heightOffset;
			}

			// Token: 0x04000116 RID: 278
			public Grounding grounding;

			// Token: 0x04000117 RID: 279
			public Vector3 lastRootPosition;

			// Token: 0x04000118 RID: 280
			public float damperF;

			// Token: 0x04000119 RID: 281
			public bool initiated;

			// Token: 0x0400011A RID: 282
			public float lastTime;
		}
	}
}
